CustomTool   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 58
dl 0
loc 79
rs 10
c 0
b 0
f 0
wmc 8

4 Functions

Rating   Name   Duplication   Size   Complexity  
A isInstalled 0 2 1
A uninstall 0 17 3
A install 0 24 3
A isValidShasum 0 5 1
1
import execa from 'execa'
2
import * as fs from 'fs'
3
import {chmodSync, existsSync, unlinkSync} from 'fs'
4
import OS from '../client/OS'
5
import {error, info, success} from '../utils/console'
6
import Tool from './tool'
7
8
abstract class CustomTool extends Tool {
9
10
    abstract name: string
11
    abstract alias: string
12
13
    abstract url: string
14
    abstract shasum: string
15
16
    binLocation = `${OS.getInstance().usrLocalDir}/bin`
17
18
    /**
19
     * Install the binary.
20
     */
21
    install = async (): Promise<boolean> => {
22
        if (await this.isInstalled()) {
23
            error(`${this.name} already is installed. Execute it by running ${this.alias}`)
24
            return false
25
        }
26
27
        const fileName = this.url.substring(this.url.lastIndexOf('/') + 1)
28
29
        info(`Downloading binary for ${this.name}...`)
30
31
        await execa('curl', ['-OL', this.url], {cwd: '/tmp/'})
32
33
        if (!(await this.isValidShasum(`/tmp/${fileName}`))) {
34
            error(`Unable to install ${this.name}. The checksum ${this.shasum} is not equal to the one of the downloaded file.`)
35
            await unlinkSync(`/tmp/${fileName}`)
36
            return false
37
        }
38
39
        await fs.copyFileSync(`/tmp/${fileName}`, `${this.binLocation}/${this.alias}`)
40
        await chmodSync(`${this.binLocation}/${this.alias}`, 0o777)
41
42
        success(`Successfully installed ${this.name}.`)
43
44
        return true
45
    }
46
47
    /**
48
     * Uninstall the binary
49
     */
50
    uninstall = async (): Promise<boolean> => {
51
        if (!(await this.isInstalled())) {
52
            error(`${this.name} is not installed`)
53
            return false
54
        }
55
56
        info(`Uninstalling ${this.name}...`)
57
58
        try {
59
            await unlinkSync(`${this.binLocation}/${this.alias}`)
60
        } catch (e) {
61
            throw new Error(`Unable to uninstall ${this.name}. Please remove the file manually to continue:\nrm${this.binLocation}/${this.alias}`)
62
        }
63
64
        success(`Uninstalled ${this.name}.`)
65
66
        return true
67
    }
68
69
    /**
70
     * Check if the binary of the app exists.
71
     */
72
    isInstalled = async (): Promise<boolean> => {
73
        return existsSync(`${this.binLocation}/${this.alias}`)
74
    }
75
76
    /**
77
     * Check if the file has a valid shasum.
78
     *
79
     * @param path
80
     */
81
    isValidShasum = async (path: string): Promise<boolean> => {
82
        const {stdout} = await execa('shasum', ['-a256', path])
83
        const shasum = stdout.replace(path, '').trim()
84
85
        return shasum === this.shasum
86
    }
87
88
}
89
90
export default CustomTool
91